package test.web;

import app.framework.constant.FrontConstants;
import app.framework.front.util.WebUtil;
import jasmine.framework.common.util.CheckUtil;
import jasmine.framework.common.util.JsonUtil;
import jasmine.framework.database.datasource.DataSourceContext;
import jasmine.framework.database.datasource.DataSourceContextHolder;
import jasmine.framework.database.impl.datasource.DefaultDataSourceContext;
import jasmine.framework.web.entity.WebResult;
import test.datasource.UnitTestDataSource;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author mh.z
 */
public class AppTestFilter implements Filter {
    private static UnitTestDataSource unitTestDataSource;

    private static final String UNITTEST_SETUP_REQUEST_URL = "/web-front/unitTest/setUp";
    private static final String UNITTEST_TEARDOWN_REQUEST_URL = "/web-front/unitTest/tearDown";

    public static void setUnitTestDataSource(UnitTestDataSource unitTestDataSource) {
        AppTestFilter.unitTestDataSource = unitTestDataSource;
    }

    @Override
    public void destroy() {
        unitTestDataSource.close();
    }

    @Override
    public synchronized void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String url = WebUtil.getRequestUriWithoutContextPath(httpRequest);


        if (UNITTEST_SETUP_REQUEST_URL.equals(url)) {
            // 测试前置处理
            unitTestDataSource.setUp();

            sendOk(httpResponse);
        } else if (UNITTEST_TEARDOWN_REQUEST_URL.equals(url)) {
            // 测试后置处理
            unitTestDataSource.tearDown();

            sendOk(httpResponse);
        } else {
            try {
                // 设置成单元测试数据源
                DataSourceContext context = new DefaultDataSourceContext(
                        UnitTestDataSource.UNIT_TEST_DATA_SOURCE_NAME);
                DataSourceContextHolder.setContext(context);

                chain.doFilter(request, response);
            } finally {
                DataSourceContextHolder.clearContext();
            }
        }
    }

    /**
     * 返回成功结果
     *
     * @param httpResponse
     */
    protected void sendOk(HttpServletResponse httpResponse) {
        CheckUtil.notNull(httpResponse, "httpResponse null");

        // 设置响应体信息
        WebUtil.setResponseInfo(httpResponse, HttpServletResponse.SC_OK,
                FrontConstants.RESPONSE_CONTENT_TYPE_JSON);

        WebResult result = WebResult.success();
        // 返回响应信息
        String json = JsonUtil.toJson(result);
        WebUtil.writeAndFlush(httpResponse, json);
    }

}
